#include <QFileDialog>

#include "DXFHandler.h"
#include "CmdManager.h"
#include "Registry.h"
#include "ActorTable.h"
#include "Scene.h"
#include "SendPointHandlerBase.h"
#include "mainwindow.h"
#include "QtOSGWidget.h"
#include "ViewerExt.h"
#include "DxfReader.h"
#include "Dxf3Reader.h"
#include "DxfData.h"
#include "AcadEntities.h"
#include "LineStrip2D.h"
#include "LineStrip3D.h"
#include "Arc2D.h" 
#include "Arc3D.h" 
#include "Spline3D.h" 
#include "Pline2D.h" 
#include "Operation/OpAdd.h"
#include "DxfItem.h"
#include "Manipulator/SwitchViewManipulator.h"
#include "Manipulator/MouseCenterManipulator.h"
#include "Manipulator/RotateManipulator.h"
#include "geometricUtility.h"

using MyManipulator = SwitchViewManipulator<MouseCenterManipulator<RotateManipulator>>;

void viewAll()
{
	Registry &reg = Registry::instance();
	auto widget3D = reg.get<QtOSGWidget>(widget3DID);
	auto osgViewer = widget3D->getViewer();
	auto manipulator = osgViewer->getCameraManipulator();
	auto myman = static_cast<MyManipulator*>(manipulator);
	if (myman)
		myman->toView(osgViewer->getCamera(), true);
}

void delayedViewAll(int milliSec)
{
	QTimer::singleShot(100, viewAll);
}

const osg::Vec4 & toColor(std::shared_ptr<DXF::EntAttribute> ent,const std::shared_ptr<DXF::DxfData>& dxfData)
{
	static osg::Vec4 table[] = {
		osg::Vec4(0,0,0,1),
		osg::Vec4(1,0,0,1),
		osg::Vec4(1,1,0,1),
		osg::Vec4(0,1,0,1),
		osg::Vec4(0,1,1,1),
		osg::Vec4(0,0,1,1),
		osg::Vec4(1,0,1,1),
		osg::Vec4(1,1,1,1),
		osg::Vec4(65/255,65/255,65/255,1),
		osg::Vec4(128/255,128/255,128/255,1),
		osg::Vec4(1,0,0,1),
		osg::Vec4(1,170/255,170/255,1),
		osg::Vec4(189/255,0,0,1),
		osg::Vec4(189/255,126/255,126/255,1),
		osg::Vec4(129/255,0,0,1),
		osg::Vec4(129/255,86/255,86/255,1),
		osg::Vec4(104/255,0,0,1),
		osg::Vec4(104/255,69/255,69/255,1),
		osg::Vec4(79/255,0,0,1),
		osg::Vec4(79/255,53/255,53/255,1),
		osg::Vec4(1,63/255,0,1),
		osg::Vec4(1,191/255,170/255,1),
		osg::Vec4(189/255,46/255,0,1),
		osg::Vec4(189/255,141/255,126/255,1),
		osg::Vec4(129/255,31/255,0,1),
		osg::Vec4(129/255,96/255,86/255,1),
		osg::Vec4(104/255,25/255,0,1),
		osg::Vec4(104/255,78/255,69/255,1),
		osg::Vec4(79/255,19/255,0,1),
		osg::Vec4(79/255,59/255,53/255,1),
		osg::Vec4(1,127/255,0,1),
		osg::Vec4(1,212/255,170/255,1),
		osg::Vec4(189/255,94/255,0,1),
		osg::Vec4(189/255,157/255/255,126/255,1),
		osg::Vec4(129/255,64/255,0,1),
		osg::Vec4(129/255,107/255,86/255,1),
		osg::Vec4(104/255,52/255,0,1),
		osg::Vec4(104/255,86/255,69/255,1),
		osg::Vec4(79/255,39/255,0,1),
		osg::Vec4(79/255,66/255,53/255,1),
		osg::Vec4(1,191/255,0,1),
		osg::Vec4(1,234/255,170/255,1),
		osg::Vec4(189/255,141/255,0,1),
		osg::Vec4(189/255,173/255,126/255,1),
		osg::Vec4(129/255,96/255,0,1),
		osg::Vec4(129/255,118/255,86/255,1),
		osg::Vec4(104/255,78/255,0,1),
		osg::Vec4(104/255,95/255,69/255,1),
		osg::Vec4(79/255,59/255,0,1),
		osg::Vec4(79/255,73/255,53/255,1),
		osg::Vec4(1,1,0,1),
		osg::Vec4(1,1,170/255,1),
		osg::Vec4(189/255,189/255,0,1),
		osg::Vec4(189/255,189/255,126/255,1),
		osg::Vec4(129/255,129/255,0,1),
		osg::Vec4(129/255,129/255,86/255,1),
		osg::Vec4(104/255,104/255,0,1),
		osg::Vec4(104/255,104/255,69/255,1),
		osg::Vec4(79/255,79/255,0,1),
		osg::Vec4(79/255,79/255,53/255,1),
		osg::Vec4(191/255,1,0,1),
		osg::Vec4(234/255,1,170/255,1),
		osg::Vec4(141/255,189/255,0,1),
		osg::Vec4(173/255,189/255,126/255,1),
		osg::Vec4(96/255,129/255,0,1),
		osg::Vec4(118/255,129/255,86/255,1),
		osg::Vec4(78/255,104/255,0,1),
		osg::Vec4(95/255,104/255,69/255,1),
		osg::Vec4(59/255,79/255,0,1),
		osg::Vec4(73/255,79/255,53/255,1),
		osg::Vec4(127/255,1,0,1),
		osg::Vec4(212/255,1,170/255,1),
		osg::Vec4(94/255,189/255,0,1),
		osg::Vec4(157/255,189/255,126/255,1),
		osg::Vec4(64/255,129/255,0,1),
		osg::Vec4(107/255,129/255,86/255,1),
		osg::Vec4(52/255,104/255,0,1),
		osg::Vec4(86/255,104/255,69/255,1),
		osg::Vec4(39/255,79/255,0,1),
		osg::Vec4(66/255,79/255,53/255,1),
		osg::Vec4(63/255,1,0,1),
		osg::Vec4(191/255,1,170/255,1),
		osg::Vec4(46/255,189/255,0,1),
		osg::Vec4(141/255,189/255,126/255,1),
		osg::Vec4(31/255,129/255,0,1),
		osg::Vec4(96/255,129/255,86/255,1),
		osg::Vec4(25/255,104/255,0,1),
		osg::Vec4(78/255,104/255,69/255,1),
		osg::Vec4(19/255,79/255,0,1),
		osg::Vec4(59/255,79/255,53/255,1),
		osg::Vec4(0,1,0,1),
		osg::Vec4(170/255,1,170/255,1),
		osg::Vec4(0,189/255,0,1),
		osg::Vec4(126/255,189/255,126/255,1),
		osg::Vec4(0,129/255,0,1),
		osg::Vec4(86/255,129/255,86/255,1),
		osg::Vec4(0,104/255,0,1),
		osg::Vec4(69/255,104/255,69/255,1),
		osg::Vec4(0,79/255,0,1),
		osg::Vec4(53/255,79/255,53/255,1),
		osg::Vec4(0,1,63/255,1),
		osg::Vec4(170/255,1,191/255,1),
		osg::Vec4(0,189/255,46/255,1),
		osg::Vec4(126/255,189/255,141/255,1),
		osg::Vec4(0,129/255,31/255,1),
		osg::Vec4(86/255,129/255,96/255,1),
		osg::Vec4(0,104/255,25/255,1),
		osg::Vec4(69/255,104/255,78/255,1),
		osg::Vec4(0,79/255,19/255,1),
		osg::Vec4(53/255,79/255,59/255,1),
		osg::Vec4(0,1,127/255,1),
		osg::Vec4(170/255,1,212/255,1),
		osg::Vec4(0,189/255,94/255,1),
		osg::Vec4(126/255,189/255,157/255,1),
		osg::Vec4(0,129/255,64/255,1),
		osg::Vec4(86/255,129/255,107/255,1),
		osg::Vec4(0,104/255,52/255,1),
		osg::Vec4(69/255,104/255,86/255,1),
		osg::Vec4(0,79/255,39/255,1),
		osg::Vec4(53/255,79/255,66/255,1),
		osg::Vec4(0,1,191/255,1),
		osg::Vec4(170/255,1,234/255,1),
		osg::Vec4(0,189/255,141/255,1),
		osg::Vec4(126/255,189/255,173/255,1),
		osg::Vec4(0,129/255,96/255,1),
		osg::Vec4(86/255,129/255,118/255,1),
		osg::Vec4(0,104/255,78/255,1),
		osg::Vec4(69/255,104/255,95/255,1),
		osg::Vec4(0,79/255,59/255,1),
		osg::Vec4(53/255,79/255,73/255,1),
		osg::Vec4(0,1,1,1),
		osg::Vec4(170/255,1,1,1),
		osg::Vec4(0,189/255,189/255,1),
		osg::Vec4(126/255,189/255,189/255,1),
		osg::Vec4(0,129/255,129/255,1),
		osg::Vec4(86/255,129/255,129/255,1),
		osg::Vec4(0,104/255,104/255,1),
		osg::Vec4(69/255,104/255,104/255,1),
		osg::Vec4(0,79/255,79/255,1),
		osg::Vec4(53/255,79/255,79/255,1),
		osg::Vec4(0,191/255,1,1),
		osg::Vec4(170/255,234/255,1,1),
		osg::Vec4(0,141/255,189/255,1),
		osg::Vec4(126/255,173/255,189/255,1),
		osg::Vec4(0,96/255,129/255,1),
		osg::Vec4(86/255,118/255,129/255,1),
		osg::Vec4(0,78/255,104/255,1),
		osg::Vec4(69/255,95/255,104/255,1),
		osg::Vec4(0,59/255,79/255,1),
		osg::Vec4(53/255,73/255,79/255,1),
		osg::Vec4(0,127/255,1,1),
		osg::Vec4(170/255,212/255,1,1),
		osg::Vec4(0,94/255,189/255,1),
		osg::Vec4(126/255,157/255,189/255,1),
		osg::Vec4(0,64/255,129/255,1),
		osg::Vec4(86/255,107/255,129/255,1),
		osg::Vec4(0,52/255,104/255,1),
		osg::Vec4(69/255,86/255,104/255,1),
		osg::Vec4(0,39/255,79/255,1),
		osg::Vec4(53/255,66/255,79/255,1),
		osg::Vec4(0,63/255,1,1),
		osg::Vec4(170/255,191/255,1,1),
		osg::Vec4(0,46/255,189/255,1),
		osg::Vec4(126/255,141/255,189/255,1),
		osg::Vec4(0,31/255,129/255,1),
		osg::Vec4(86/255,96/255,129/255,1),
		osg::Vec4(0,25/255,104/255,1),
		osg::Vec4(69/255,78/255,104/255,1),
		osg::Vec4(0,19/255,79/255,1),
		osg::Vec4(53/255,59/255,79/255,1),
		osg::Vec4(0,0,1,1),
		osg::Vec4(170/255,170/255,1,1),
		osg::Vec4(0,0,189/255,1),
		osg::Vec4(126/255,126/255,189/255,1),
		osg::Vec4(0,0,129/255,1),
		osg::Vec4(86/255,86/255,129/255,1),
		osg::Vec4(0,0,104/255,1),
		osg::Vec4(69/255,69/255,104/255,1),
		osg::Vec4(0,0,79/255,1),
		osg::Vec4(53/255,53/255,79/255,1),
		osg::Vec4(63/255,0,1,1),
		osg::Vec4(191/255,170/255,1,1),
		osg::Vec4(46/255,0,189/255,1),
		osg::Vec4(141/255,126/255,189/255,1),
		osg::Vec4(31/255,0,129/255,1),
		osg::Vec4(96/255,86/255,129/255,1),
		osg::Vec4(25/255,0,104/255,1),
		osg::Vec4(78/255,69/255,104/255,1),
		osg::Vec4(19/255,0,79/255,1),
		osg::Vec4(59/255,53/255,79/255,1),
		osg::Vec4(127/255,0,1,1),
		osg::Vec4(212/255,170/255,1,1),
		osg::Vec4(94/255,0,189/255,1),
		osg::Vec4(157/255,126/255,189/255,1),
		osg::Vec4(64/255,0,129/255,1),
		osg::Vec4(107/255,86/255,129/255,1),
		osg::Vec4(52/255,0,104/255,1),
		osg::Vec4(86/255,69/255,104/255,1),
		osg::Vec4(39/255,0,79/255,1),
		osg::Vec4(66/255,53/255,79/255,1),
		osg::Vec4(191/255,0,1,1),
		osg::Vec4(234/255,170/255,1,1),
		osg::Vec4(141/255,0,189/255,1),
		osg::Vec4(173/255,126/255,189/255,1),
		osg::Vec4(96/255,0,129/255,1),
		osg::Vec4(118/255,86/255,129/255,1),
		osg::Vec4(78/255,0,104/255,1),
		osg::Vec4(95/255,69/255,104/255,1),
		osg::Vec4(59/255,0,79/255,1),
		osg::Vec4(73/255,53/255,79/255,1),
		osg::Vec4(1,0,1,1),
		osg::Vec4(1,170/255,1,1),
		osg::Vec4(189/255,0,189/255,1),
		osg::Vec4(189/255,126/255,189/255,1),
		osg::Vec4(129/255,0,129/255,1),
		osg::Vec4(129/255,86/255,129/255,1),
		osg::Vec4(104/255,0,104/255,1),
		osg::Vec4(104/255,69/255,104/255,1),
		osg::Vec4(79/255,0,79/255,1),
		osg::Vec4(79/255,53/255,79/255,1),
		osg::Vec4(1,0,191/255,1),
		osg::Vec4(1,170/255,234/255,1),
		osg::Vec4(189/255,0,141/255,1),
		osg::Vec4(189/255,126/255,173/255,1),
		osg::Vec4(129/255,0,96/255,1),
		osg::Vec4(129/255,86/255,118/255,1),
		osg::Vec4(104/255,0,78/255,1),
		osg::Vec4(104/255,69/255,95/255,1),
		osg::Vec4(79/255,0,59/255,1),
		osg::Vec4(79/255,53/255,73/255,1),
		osg::Vec4(1,0,127/255,1),
		osg::Vec4(1,170/255,212/255,1),
		osg::Vec4(189/255,0,94/255,1),
		osg::Vec4(189/255,126/255,157/255,1),
		osg::Vec4(129/255,0,64/255,1),
		osg::Vec4(129/255,86/255,107/255,1),
		osg::Vec4(104/255,0,52/255,1),
		osg::Vec4(104/255,69/255,86/255,1),
		osg::Vec4(79/255,0,39/255,1),
		osg::Vec4(79/255,53/255,66/255,1),
		osg::Vec4(1,0,63/255,1),
		osg::Vec4(1,170/255,191/255,1),
		osg::Vec4(189/255,0,46/255,1),
		osg::Vec4(189/255,126/255,141/255,1),
		osg::Vec4(129/255,0,31/255,1),
		osg::Vec4(129/255,86/255,96/255,1),
		osg::Vec4(104/255,0,25/255,1),
		osg::Vec4(104/255,69/255,78/255,1),
		osg::Vec4(79/255,0,19/255,1),
		osg::Vec4(79/255,53/255,59/255,1),
		osg::Vec4(51/255,51/255,51/255,1),
		osg::Vec4(80/255,80/255,80/255,1),
		osg::Vec4(105/255,105/255,105/255,1),
		osg::Vec4(130/255,130/255,130/255,1),
		osg::Vec4(190/255,190/255,190/255,1),
		osg::Vec4(1,1,1,1),
	};
	if (ent->m_Color >= acByLayer)
	{
		const DXF::LayerData* ld = getLayerData(dxfData, ent->m_Layer);
		if (ld)
			ent->m_Color = (AcColor)ld->m_Color;
	}

	if (ent->m_Color == acWhite || ent->m_Color >= acByLayer || ent->m_Color < acByBlock)
	{
		ent->m_Color = acBlack;
	}
	return table[ent->m_Color];
}

osg::Vec3d convert(const DXF::CDblPoint3& point)
{
	return osg::Vec3d(point.x, point.y, point.z);
}

std::vector<osg::Vec3d> convert(const std::vector<DXF::CDblPoint3>& points)
{
	std::vector<osg::Vec3d> result;
	for (const auto& pt : points)
	{
		result.push_back(osg::Vec3d(pt.x, pt.y, pt.z));
	}
	return result;
}

DXFHandler::DXFHandler()
{
}

DXFHandler::~DXFHandler()
{
}

void DXFHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	if (data.type() == QVariant::Bool && !data.toBool())
	{
		emit finished();
		return;
	}

	if (status() == 0)
	{
		remark(tr("DXF文件名:"));
		bool success = openDxfFile();
		if (success && !m_nodes.empty())
		{
			auto sph = getSendPointHandler();
			if (sph)
			{
				sph->setPointMask(CS_LBTNDOWN | CS_MOUSEMOVE);
			}
			enableMouseHandler(MouseHandlerID::PointSender);
			prompt(1, tr("指定插入点或者[DXF基点(b)]<0,0>:"));
		}
		else
		{
			emit finished();
		}
		return;
	}

	if (status() == 1)
	{
		auto scene = getScene();
		auto ucs = scene->getCurrentUCS();
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_insertPt.set(0, 0, 0);
		}
		else if (bool success = getPoint2D(*ucs, data, rawInput, cs, m_insertPt))
		{
			if (cs == CS_MOUSEMOVE)
				return;
		}
		else
		{
			if (data.type() == QVariant::String)
			{
				auto sph = getSendPointHandler();
				QString text = data.toString();
				if (text.compare("B", Qt::CaseInsensitive) == 0)
				{
					prompt(2, tr("指定DXF基点<0,0>:"));
					return;
				}
			}
			return;
		}
		auto sph = getSendPointHandler();
		sph->setPointMask(0);
		prompt(3, tr("指定比例因子[米(m)/厘米(cm)/毫米(mm)]<m>:"));
		return;
	}

	if (status() == 2)
	{
		auto scene = getScene();
		auto ucs = scene->getCurrentUCS();
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_basePt.set(0, 0, 0);
		}
		else if (bool success = getPoint2D(*ucs, data, rawInput, cs, m_basePt))
		{
			if (cs == CS_MOUSEMOVE)
				return;
		}
		else
		{
			remark(tr("无效的输入"));
			return;
		}
		auto sph = getSendPointHandler();
		sph->setPointMask(0);
		prompt(3, tr("指定比例因子[米(m)/厘米(cm)/毫米(mm)]<m>:"));
		return;
	}

	if (status() == 3)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_scale = 1.0;
		}
		else if (data.type() == QVariant::String)
		{
			auto sph = getSendPointHandler();
			QString text = data.toString();
			if (text.compare("cm", Qt::CaseInsensitive) == 0)
			{
				m_scale = 100;
			}
			else if (text.compare("mm", Qt::CaseInsensitive) == 0)
			{
				m_scale = 1000;
			}
		}
		else
		{
			remark(tr("无效的输入"));
			return;
		}
		prompt(4, tr("指定旋转角度<0>:"));
		return;
	}

	if (status() == 4)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_angle = 0.0;
		}
		else if (data.type() == QVariant::Double)
		{
			m_angle = data.toDouble();
		}
		else
		{
			remark(tr("无效的输入"));
			return;
		}

		if (m_scale != 1.0)
		{
			for (const auto& node : m_nodes)
			{
				auto ent = dynamic_cast<Ent2D*>(node.get());
				if (ent)
					ent->scale(m_basePt, m_scale);
			}
		}

		if (m_angle != 0)
		{
			for (const auto& node : m_nodes)
			{
				auto ent = dynamic_cast<Ent2D*>(node.get());
				if (ent)
					ent->rotate(m_angle * M_PI / 180.0, osg::Vec2d(m_basePt.x(), m_basePt.y()));
			}
		}

		osg::Vec3d offset = m_insertPt - m_basePt;
		if (offset != osg::Vec3d())
		{
			for (const auto& node : m_nodes)
			{
				auto ent = dynamic_cast<Ent*>(node.get());
				if (ent)
					ent->move(offset);
			}
		}
		auto scene = getScene();
		auto undoStack = scene->undoStack();
		undoStack->push(new OpAdd(m_nodes));
		delayedViewAll(100);
		emit finished();
		return;
	}
}

CDblPoint osgPointToCDblPoint(const osg::Vec3d& point);

std::set<std::shared_ptr<INode>> dxfDataToINodes(const std::shared_ptr<DXF::DxfData>& dxfData, INode* parent)
{
	std::set<std::shared_ptr<INode>> children;
	for (auto ent : dxfData->m_Objects)
	{
		const osg::Vec4 color = toColor(ent, dxfData);
		const auto &ti = typeid(*ent);
		if (ti == typeid(DXF::AcadLine))
		{
			DXF::AcadLine* acadLine = static_cast<DXF::AcadLine*>(ent.get());
			osg::Vec3d startPt;
			startPt.set(acadLine->m_StartPoint.x, acadLine->m_StartPoint.y, 0);
			osg::Vec3d endPt;
			endPt.set(acadLine->m_EndPoint.x, acadLine->m_EndPoint.y, 0);
			std::shared_ptr<LineStrip2D> line = std::make_shared<LineStrip2D>(parent);
			std::vector<osg::Vec3d> points;
			points.push_back(startPt);
			points.push_back(endPt);
			UCS* ucs = dynamic_cast<UCS*>(parent);
			if (ucs)
				line->setColor(ucs->getUCSColor());
			else
				line->setColor(color);
			line->setPoints(points);
			children.insert(line);
		}
		if (ti == typeid(DXF::AcadLine3))
		{
			DXF::AcadLine3* acadLine = static_cast<DXF::AcadLine3*>(ent.get());
			osg::Vec3d startPt;
			startPt.set(acadLine->m_StartPoint.x, acadLine->m_StartPoint.y, acadLine->m_StartPoint.z);
			osg::Vec3d endPt;
			endPt.set(acadLine->m_EndPoint.x, acadLine->m_EndPoint.y, acadLine->m_EndPoint.z);
			std::shared_ptr<LineStrip3D> line = std::make_shared<LineStrip3D>(parent);
			std::vector<osg::Vec3d> points;
			points.push_back(startPt);
			points.push_back(endPt);
			line->setColor(color);
			line->setPoints(points);
			children.insert(line);
		}
		else if (ti == typeid(DXF::AcadArc))
		{
			DXF::AcadArc* acadArc = static_cast<DXF::AcadArc*>(ent.get());
			osg::Vec3d center;
			center.set(acadArc->m_Center.x, acadArc->m_Center.y, 0);
			double startAngle = acadArc->m_StartAngle * M_PI / 180;
			double endAngle = acadArc->m_EndAngle * M_PI / 180;
			const double radius = acadArc->m_Radius;
			std::shared_ptr<Arc2D> arc = std::make_shared<Arc2D>(parent);
			UCS* ucs = dynamic_cast<UCS*>(parent);
			if (ucs)
				arc->setColor(ucs->getUCSColor());
			else
				arc->setColor(color);
			arc->set(center, radius, startAngle, endAngle);
			children.insert(arc);
		}
		else if (ti == typeid(DXF::AcadArc3))
		{
			DXF::AcadArc3* acadArc = static_cast<DXF::AcadArc3*>(ent.get());
			osg::Vec3d center;
			center.set(acadArc->m_Center.x, acadArc->m_Center.y, acadArc->m_Center.z);
			double startAngle = acadArc->m_StartAngle * M_PI / 180;
			double endAngle = acadArc->m_EndAngle * M_PI / 180;
			const double radius = acadArc->m_Radius;
			
			std::shared_ptr<Arc3D> arc = std::make_shared<Arc3D>(parent);
			DXF::CDblPoint3 xAxis, yAxis;
			DXF::ArbitraryAxis(acadArc->m_zAxis, xAxis, yAxis);
			arc->setAxis(osg::Vec3d(xAxis.x, xAxis.y, xAxis.z), osg::Vec3d(yAxis.x, yAxis.y, yAxis.z));
			arc->setColor(color);
			arc->set(center, radius, startAngle, endAngle);
			children.insert(arc);
		}
		else if (ti == typeid(DXF::AcadCircle))
		{
			DXF::AcadCircle* acadArc = static_cast<DXF::AcadCircle*>(ent.get());
			osg::Vec3d center;
			center.set(acadArc->m_Center.x, acadArc->m_Center.y, 0);
			double startAngle = 0;
			double endAngle = 2.0 * M_PI;
			const double radius = acadArc->m_Radius;
			std::shared_ptr<Arc2D> arc = std::make_shared<Arc2D>(parent);
			UCS* ucs = dynamic_cast<UCS*>(parent);
			if (ucs)
				arc->setColor(ucs->getUCSColor());
			else
				arc->setColor(color);
			arc->set(center, radius, startAngle, endAngle);
			children.insert(arc);
		}
		else if (ti == typeid(DXF::AcadCircle3))
		{
			DXF::AcadCircle3* acadArc = static_cast<DXF::AcadCircle3*>(ent.get());
			osg::Vec3d center;
			center.set(acadArc->m_Center.x, acadArc->m_Center.y, acadArc->m_Center.z);
			double startAngle = 0;
			double endAngle = 2.0 * M_PI;
			const double radius = acadArc->m_Radius;
			
			std::shared_ptr<Arc3D> arc = std::make_shared<Arc3D>(parent);
			DXF::CDblPoint3 xAxis, yAxis;
			DXF::ArbitraryAxis(acadArc->m_zAxis, xAxis, yAxis);
			arc->setAxis(osg::Vec3d(xAxis.x, xAxis.y, xAxis.z), osg::Vec3d(yAxis.x, yAxis.y, yAxis.z));
			arc->setColor(color);
			arc->set(center, radius, startAngle, endAngle);
			children.insert(arc);
		}
		else if (ti == typeid(DXF::AcadSpline3))
		{
			DXF::AcadSpline3* acadSpline = static_cast<DXF::AcadSpline3*>(ent.get());
			std::shared_ptr<Spline3D> spline = std::make_shared<Spline3D>(parent);
			spline->setColor(color);
			spline->setFlag(acadSpline->m_Flag);
			spline->setDegree(acadSpline->m_Degree);
			spline->setCtrlPoints(convert(acadSpline->m_ControlPoints));
			spline->setKnots(acadSpline->m_Knots);
			spline->setWeights(acadSpline->m_Weights);
			children.insert(spline);
		}
		else if (ti == typeid(DXF::AcadLWPLine))
		{
			DXF::AcadLWPLine* acadLWPLine = static_cast<DXF::AcadLWPLine*>(ent.get());
			std::vector<osg::Vec3> pts;
			for (const auto& v : acadLWPLine->m_Vertices)
			{
				pts.push_back(osg::Vec3(v.x, v.y, 0));
			}
			int count = pts.size() - 1;
			std::vector<PlineNode> nodes;
			for (int i = 0; i <= count; i++)
			{
				auto pt = pts[i];
				auto bulge = acadLWPLine->GetBulge(i);
				PlineNode node(pt, bulge);
				nodes.push_back(node);
			}
			if (acadLWPLine->m_Closed)
			{
				auto pt = pts[0];
				auto bulge = acadLWPLine->GetBulge(0);
				PlineNode node(pt, bulge);
				nodes.push_back(node);
				count++;
			}
			for (int i = 0; i <= count - 1; i++)
			{
				if (nodes[i].m_bulge == 0)
				{
					std::shared_ptr<LineStrip2D> line = std::make_shared<LineStrip2D>(parent);
					std::vector <osg::Vec3d> points;
					points.push_back(nodes[i].m_point);
					points.push_back(nodes[i + 1].m_point);
					line->setPoints(points);
					line->setColor(color);
					children.insert(line);
				}
				else
				{
					std::shared_ptr<Arc2D> arc2D = std::make_shared<Arc2D>(parent);
					CDblPoint center;
					double radius;
					double startAng;
					double sweepAngle;
					bool success = CalArcFromSEB(osgPointToCDblPoint(nodes[i].m_point), osgPointToCDblPoint(nodes[i + 1].m_point), 
						nodes[i].m_bulge, center, radius, startAng, sweepAngle);
					startAng = startAng * M_PI / 180;
					sweepAngle = sweepAngle * M_PI / 180;
					double endAng = startAng + sweepAngle;
					if (sweepAngle < 0.0)
						std::swap(startAng, endAng);
					arc2D->set(osg::Vec3d(center.x, center.y, 0), radius, startAng, endAng);
					arc2D->setColor(color);
					children.insert(arc2D);
				}
			}
		}
	}
	return children;
}

bool DXFHandler::openDxfFile()
{
	Registry &reg = Registry::instance();
	MainWindow * main = reg.get<MainWindow>(mainWindowID);
	auto fileName = QFileDialog::getOpenFileName(main, tr("打开文件"), "", tr("DXF(*.dxf)"));
	if (fileName.isEmpty())
		return false;
	return openDxfFile(fileName);
}

bool DXFHandler::openDxfFile(const QString & fileName)
{
	auto dxfData = std::make_shared<DXF::DxfData>();
	DXF::DxfReader dxfRead(*dxfData);
	bool success = dxfRead.ReadDxf(fileName.toLocal8Bit().data(), false);
	if (!success)
	{
		remark(tr("该文件已打开，请关闭再导入"));
		return false;
	}
	auto scene = getScene();
	auto ucs = scene->getCurrentUCS();
	m_nodes = dxfDataToINodes(dxfData, ucs.get());
	return success;
}

DXF3Handler::DXF3Handler()
{
}

DXF3Handler::~DXF3Handler()
{
}

void DXF3Handler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	if (data.type() == QVariant::Bool && !data.toBool())
	{
		emit finished();
		return;
	}

	if (status() == 0)
	{
		remark(tr("DXF文件名:"));
		bool success = openDxfFile();
		if (success && !m_nodes.empty())
		{
			auto sph = getSendPointHandler();
			if (sph)
			{
				sph->setPointMask(CS_LBTNDOWN | CS_MOUSEMOVE);
			}
			enableMouseHandler(MouseHandlerID::PointSender);
			prompt(1, tr("指定插入点或者[DXF基点(b)]<0,0,0>:"));
		}
		else
		{
			emit finished();
		}
		return;
	}

	if (status() == 1)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_insertPt.set(0, 0, 0);
		}
		else if (data.type() == QVariant::Vector3D)
		{
			auto pt = data.value<QVector3D>();
			m_insertPt.set(pt.x(), pt.y(), pt.z());
			if (cs == CS_MOUSEMOVE)
				return;
		}
		else
		{
			if (data.type() == QVariant::String)
			{
				auto sph = getSendPointHandler();
				QString text = data.toString();
				if (text.compare("B", Qt::CaseInsensitive) == 0)
				{
					prompt(2, tr("指定DXF基点<0,0,0>:"));
				}
			}
			return;
		}
		auto sph = getSendPointHandler();
		sph->setPointMask(0);
		prompt(3, tr("指定比例因子[米(m)/厘米(cm)/毫米(mm)]<m>:"));
		return;
	}

	if (status() == 2)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_basePt.set(0, 0, 0);
		}
		else if (data.type() == QVariant::Vector3D)
		{
			auto pt = data.value<QVector3D>();
			m_basePt.set(pt.x(), pt.y(), pt.z());
			if (cs == CS_MOUSEMOVE)
				return;
		}
		else
		{
			remark(tr("无效的输入"));
			return;
		}
		auto sph = getSendPointHandler();
		sph->setPointMask(0);
		prompt(3, tr("指定比例因子[米(m)/厘米(cm)/毫米(mm)]<m>:"));
		return;
	}

	if (status() == 3)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			m_scale = 1.0;
		}
		else if (data.type() == QVariant::String)
		{
			auto sph = getSendPointHandler();
			QString text = data.toString();
			if (text.compare("cm", Qt::CaseInsensitive) == 0)
			{
				m_scale = 100;
			}
			else if (text.compare("mm", Qt::CaseInsensitive) == 0)
			{
				m_scale = 1000;
			}
		}
		else
		{
			remark(tr("无效的输入"));
			return;
		}

		if (m_scale != 1.0)
		{
			for (const auto& node : m_nodes)
			{
				auto ent = dynamic_cast<Ent*>(node.get());
				if (ent)
					ent->scale(m_basePt, m_scale);
			}
		}

		osg::Vec3d offset = m_insertPt - m_basePt;
		if (offset != osg::Vec3d())
		{
			for (const auto& node : m_nodes)
			{
				auto ent = dynamic_cast<Ent*>(node.get());
				if (ent)
					ent->move(offset);
			}
		}

		auto scene = getScene();
		auto undoStack = scene->undoStack();
		undoStack->push(new OpAdd(m_nodes));
		delayedViewAll(100);
		emit finished();
		return;
	}
}

bool DXF3Handler::openDxfFile()
{
	Registry &reg = Registry::instance();
	MainWindow * main = reg.get<MainWindow>(mainWindowID);
	auto fileName = QFileDialog::getOpenFileName(main, tr("打开文件"), "", tr("DXF(*.dxf)"));
	if (fileName.isEmpty())
		return false;
	return openDxfFile(fileName);
}

bool DXF3Handler::openDxfFile(const QString & fileName)
{
	auto scene = getScene();
	auto dxfData = std::make_shared<DXF::DxfData>();
	DXF::Dxf3Reader dxfRead(*dxfData);
	bool success = dxfRead.ReadDxf(fileName.toLocal8Bit().data(), true);
	if (!success)
	{
		remark(tr("该文件已打开，请关闭再导入"));
		return false;
	}
	m_nodes = dxfDataToINodes(dxfData, scene);
	delayedViewAll(100);
	return success;
}
